#include "epoll_server.h"

epoll_server_t *epoll_server_init(unsigned short port)
{
    epoll_server_t *server = (epoll_server_t *)malloc(sizeof(epoll_server_t));
    if (!server)
    {
        perror("malloc");
        return NULL;
    }

    // 创建套接字
    server->listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server->listen_fd < 0)
    {
        perror("socket");
        free(server);
        return NULL;
    }

    // 设置地址重用
    int opt = 1;
    setsockopt(server->listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&addr.sin_zero, 8);

    if (bind(server->listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("bind");
        free(server);
        return NULL;
    }

    if (listen(server->listen_fd, 3) < 0)
    {
        perror("listen");
        free(server);
        return NULL;
    }

    // 创建epoll
    server->epoll_fd = epoll_create1(0);
    if (server->epoll_fd < 0)
    {
        perror("epoll_create");
        free(server);
        return NULL;
    }

    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = server->listen_fd;

    if (epoll_ctl(server->epoll_fd, EPOLL_CTL_ADD, server->listen_fd, &event) < 0)
    {
        perror("epoll_ctl");
        free(server);
        return NULL;
    }

    printf("服务器启动，监听端口: %d\n", port);
    return server;
}

void epoll_server_start(epoll_server_t *server)
{
    struct epoll_event events[MAX_EVENTS];
    while (1)
    {
        int nfds = epoll_wait(server->epoll_fd, events, MAX_EVENTS, -1);
        if (nfds == -1)
        {
            perror("epoll_wait");
            break;
        }
        printf("nfds:%d\n",nfds);

        for (int i = 0; i < nfds; ++i)
        {
            if (events[i].data.fd == server->listen_fd)
            {
                // 处理新连接
                struct sockaddr_in client_addr;
                socklen_t client_len = sizeof(client_addr);
                int conn_fd = accept(server->listen_fd, (struct sockaddr *)&client_addr, &client_len);
                if (conn_fd < 0)
                {
                    perror("accept");
                    continue;
                }

                struct epoll_event event;
                event.events = EPOLLIN | EPOLLET;
                event.data.fd = conn_fd;
                if (epoll_ctl(server->epoll_fd, EPOLL_CTL_ADD, conn_fd, &event) < 0)
                {
                    perror("epoll_ctl");
                    close(conn_fd);
                    continue;
                }

                printf("新连接: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
            }
            else
            {
                // 处理数据读取
                char buffer[BUFFER_SIZE];
                int n = read(events[i].data.fd, buffer, BUFFER_SIZE);
                printf("user[%d]\n", events[i].data.fd);
                if (n < 0)
                {
                    perror("read");
                    close(events[i].data.fd);
                    epoll_ctl(server->epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
                    continue;
                }
                else if (n == 0)
                {
                    printf("客户端断开连接: %d\n", events[i].data.fd);
                    close(events[i].data.fd);
                    epoll_ctl(server->epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
                    continue;
                }

                buffer[n] = '\0';
                printf("接收数据: %s\n", buffer);

                // 回送数据回客户端
                char *message = "收到你的消息\n";
                write(events[i].data.fd, message, strlen(message));
            }
        }
    }
}

void epoll_server_stop(epoll_server_t *server)
{
    if (server)
    {
        close(server->epoll_fd);
        close(server->listen_fd);
        free(server);
    }
}